package dbops

import (
	"fmt"
	"gitee.com/DengAnbang/Wefore/src/bean"
	"gitee.com/DengAnbang/Wefore/src/code"
	"gitee.com/DengAnbang/Wefore/src/push"
	"gitee.com/DengAnbang/goutils/dbutils"
	"gitee.com/DengAnbang/goutils/utils"
	"time"
)

type Attendance struct {
	TodayTime string `json:"today_time"`
	StartTime int    `json:"start_time"`
	EndTime   int    `json:"end_time"`
}

func NewAttendance(data map[string]string) Attendance {
	return Attendance{
		TodayTime: data["today_time"],
		StartTime: utils.String2int(data["start_time"], 0),
		EndTime:   utils.String2int(data["end_time"], 0),
	}
}

type AskForLeave struct {
	Id          string `json:"id"`
	UserId      string `json:"user_id"`
	UserName    string `json:"user_name"`
	LeaveType   int    `json:"leave_type"`
	LeaveReason string `json:"leave_reason"`
	StartTime   int    `json:"start_time"`
	EndTime     int    `json:"end_time"`
	AskUserId   string `json:"ask_user_id"`
	AskUserName string `json:"ask_user_name"`
	AskResult   string `json:"ask_result"`
	IsRead      int    `json:"is_read"`
	Created     string `json:"created"`
	AskTime     int    `json:"ask_time"`
}

func NewAskForLeave(data map[string]string) AskForLeave {
	return AskForLeave{
		Id:          data["askForLeaveId"],
		UserId:      data["user_id"],
		UserName:    data["user_name"],
		LeaveType:   utils.String2int(data["leave_type"], 0),
		LeaveReason: data["leave_reason"],
		StartTime:   utils.String2int(data["start_time"], 0),
		EndTime:     utils.String2int(data["end_time"], 0),
		AskUserId:   data["ask_user_id"],
		AskUserName: data["ask_user_name"],
		AskResult:   data["ask_result"],
		IsRead:      utils.String2int(data["is_read"], 0),
		Created:     data["created"],
		AskTime:     utils.String2int(data["ask_time"], 0),
	}
}

//上班打卡
func AttendancePunchIn(userId string) error {
	if len(userId) == 0 {
		return bean.NewErrorMessage("用户Id不能为空")
	}
	now := time.Now().Format("2006-01-02")
	attendances, err := AttendanceSelect(userId, now, now)
	if err != nil {
		return err
	}
	//今日已经上班打过卡了
	if len(attendances) > 0 {
		return bean.NewErrorMessage("今日已经打过上班卡了!")
	}
	stmtIn, err := dbConn.Prepare("INSERT INTO table_attendance_user (user_id,start_time,end_time,today_time)VALUES(?,?,?,?)")
	if err != nil {
		return err
	}
	_, err = stmtIn.Exec(userId, time.Now().Unix(), 0, now)
	if err != nil {
		return err
	}
	_ = stmtIn.Close()
	return nil
}

//下班打卡
func AttendancePunchOut(userId string) error {
	if len(userId) == 0 {
		return bean.NewErrorMessage("用户Id不能为空")
	}
	now := time.Now().Format("2006-01-02")
	attendances, err := AttendanceSelect(userId, now, now)
	if err != nil {
		return err
	}
	//今日已经上班打过卡了
	if len(attendances) <= 0 {
		stmtIn, err := dbConn.Prepare("INSERT INTO table_attendance_user (user_id,start_time,end_time,today_time)VALUES(?,?,?,?)")
		if err != nil {
			return err
		}
		_, err = stmtIn.Exec(userId, 0, time.Now().Unix(), now)
		if err != nil {
			return err
		}
		_ = stmtIn.Close()
	} else {
		stmtIn, err := dbConn.Prepare("UPDATE table_attendance_user SET end_time=? WHERE user_id=? AND today_time=?")
		if err != nil {
			return err
		}
		_, err = stmtIn.Exec(time.Now().Unix(), userId, now)
		if err != nil {
			return err
		}
		_ = stmtIn.Close()
	}
	return nil
}

//查询某人的打卡记录
func AttendanceSelect(userId string, startTime, endTime string) ([]Attendance, error) {
	var attendances = make([]Attendance, 0)
	stmtOut, err := dbConn.Prepare(`select * from table_attendance_user where user_id=? AND date_format(today_time,'%Y-%m-%d') between ? and ? order by today_time desc`)
	if err != nil {
		return attendances, err
	}
	defer stmtOut.Close()
	rows, err := stmtOut.Query(userId, startTime, endTime)
	if err != nil {
		return attendances, err
	}
	defer rows.Close()
	for rows.Next() {
		mapStrings, err := dbutils.GetRowsMap(rows)
		if err != nil {
			return attendances, err
		}
		attendance := NewAttendance(mapStrings)
		attendances = append(attendances, attendance)
	}
	return attendances, err
}

//创建请假
func AttendanceAskForLeaveCreate(userId string, leaveType string, leaveReason, startTime, endTime, askUserId string) error {
	if len(userId) == 0 {
		return bean.NewErrorMessage("用户Id不能为空")
	}
	leaveTypeInt := utils.String2int(leaveType, 0)
	if leaveTypeInt == 0 {
		return bean.NewErrorMessage("请假类型不能为空")
	}
	if len(startTime) == 0 {
		return bean.NewErrorMessage("开始时间不能为空")
	}
	if len(endTime) == 0 {
		return bean.NewErrorMessage("结束时间不能为空")
	}
	beans, err := UserToStructureTreeSelect(userId)
	if err != nil {
		return err
	}
	if len(beans) <= 0 {
		return bean.NewErrorMessage("用户没有加入部门,请假失败!")
	}
	askUserId = beans[0].HeadUserId
	if len(askUserId) <= 0 {
		return bean.NewErrorMessage("用户所在部门没有设置领导人,请假失败!")
	}
	loc, _ := time.LoadLocation("Asia/Shanghai") //设置时区
	startTimeUnix, _ := time.ParseInLocation("2006-01-02", startTime, loc)
	endTimeUnix, _ := time.ParseInLocation("2006-01-02", endTime, loc)
	stmtIn, err := dbConn.Prepare("INSERT INTO table_attendance_askForLeave (user_id,leave_type,leave_reason,start_time,end_time,ask_user_id)VALUES(?,?,?,?,?,?)")
	if err != nil {
		return err
	}
	r, err := stmtIn.Exec(userId, leaveTypeInt, leaveReason, startTimeUnix.Unix(), endTimeUnix.Unix(), askUserId)
	if err != nil {
		return err
	}
	i, err := r.LastInsertId()
	if err != nil {
		return err
	}
	_ = stmtIn.Close()
	userBean, _ := UserSelectByUserId(userId)
	messageBean := MessageBean{
		ToUserId:       askUserId,
		MessageType:    code.TypePushAskForLeave,
		MessageContent: fmt.Sprintf("收到了%v的请假消息,请及时处理!", userBean.UserName),
		MessageAppend:  fmt.Sprint(i),
	}
	err = MessageCreate(messageBean)
	//向审批人推送
	push.Push(askUserId, code.TypePushAskForLeave, messageBean)
	return nil
}

//查询某人的请假信息
func AttendanceAskForLeaveSelectByUserId(userId string) ([]AskForLeave, error) {
	var askForLeaves = make([]AskForLeave, 0)
	if len(userId) == 0 {
		return askForLeaves, bean.NewErrorMessage("用户Id不能为空")
	}
	stmtOut, err := dbConn.Prepare(`SELECT * ,
tu1.name as user_name,
tu2.name as ask_user_name,
table_attendance_askForLeave.user_id as user_id,
tu1.user_id as tb1_user_id,
tu2.user_id as tb2_user_id
FROM table_attendance_askForLeave 
LEFT OUTER JOIN table_user tu1 on table_attendance_askForLeave.user_id = tu1.user_id
LEFT OUTER JOIN table_user tu2 on table_attendance_askForLeave.ask_user_id = tu2.user_id
where table_attendance_askForLeave.user_id=?`)
	if err != nil {
		return askForLeaves, err
	}
	rows, err := stmtOut.Query(userId)
	if err != nil {
		return askForLeaves, err
	}

	for rows.Next() {
		mapStrings, err := dbutils.GetRowsMap(rows)
		for err != nil {
			return askForLeaves, err
		}
		attendance := NewAskForLeave(mapStrings)
		askForLeaves = append(askForLeaves, attendance)
	}
	return askForLeaves, nil
}

//查询需要我审批的请假信息isRead 0未审批1以审批
func AttendanceAskForLeaveApprovalSelect(userId, isRead string) ([]AskForLeave, error) {
	var askForLeaves = make([]AskForLeave, 0)
	if len(userId) == 0 {
		return askForLeaves, bean.NewErrorMessage("用户Id不能为空")
	}
	stmtOut, err := dbConn.Prepare(`SELECT * ,
table_attendance_askForLeave.id as askForLeaveId,
tu1.name as user_name,
tu2.name as ask_user_name
FROM table_attendance_askForLeave 
LEFT OUTER JOIN table_user tu1 on table_attendance_askForLeave.user_id = tu1.user_id
LEFT OUTER JOIN table_user tu2 on table_attendance_askForLeave.ask_user_id = tu2.user_id
where ask_user_id=? And is_read=?`)
	if err != nil {
		return askForLeaves, err
	}
	rows, err := stmtOut.Query(userId, isRead)
	if err != nil {
		return askForLeaves, err
	}

	for rows.Next() {
		mapStrings, err := dbutils.GetRowsMap(rows)
		for err != nil {
			return askForLeaves, err
		}
		attendance := NewAskForLeave(mapStrings)
		askForLeaves = append(askForLeaves, attendance)
	}
	return askForLeaves, nil
}

//查询某条的请假信息
func AttendanceAskForLeaveSelectById(askForLeaveId string) (AskForLeave, error) {
	var askForLeave AskForLeave
	if len(askForLeaveId) == 0 {
		return askForLeave, bean.NewErrorMessage("假条的Id不能为空")
	}
	stmtOut, err := dbConn.Prepare(`SELECT * ,
tu1.name as user_name,
tu2.name as ask_user_name
FROM table_attendance_askForLeave 
LEFT OUTER JOIN table_user tu1 on table_attendance_askForLeave.user_id = tu1.user_id
LEFT OUTER JOIN table_user tu2 on table_attendance_askForLeave.ask_user_id = tu2.user_id
where id=?`)
	if err != nil {
		return askForLeave, err
	}
	rows, err := stmtOut.Query(askForLeaveId)
	if err != nil {
		return askForLeave, err
	}
	if rows.Next() {
		mapStrings, err := dbutils.GetRowsMap(rows)
		if err != nil {
			return askForLeave, err
		}
		askForLeave = NewAskForLeave(mapStrings)
	}
	return askForLeave, nil
}

//审批某条的请假信息
func AttendanceAskForLeaveApproval(userId, askForLeaveId string, askResult string) error {
	if len(askForLeaveId) == 0 {
		return bean.NewErrorMessage("假条的Id不能为空")
	}
	askResultInt := utils.String2int(askResult, 0)
	askForLeaveIdInt := utils.String2int(askForLeaveId, 0)
	if askResultInt != 1 && askResultInt != -1 {
		return bean.NewErrorMessage("askResult只能传1或者-1,1是同意,-1是拒绝!")
	}
	stmtIn, err := dbConn.Prepare("UPDATE table_attendance_askForLeave SET ask_result=?,ask_time=?,is_read=? WHERE id=?")
	if err != nil {
		return err
	}
	_, err = stmtIn.Exec(askResultInt, time.Now().Unix(), 1, askForLeaveIdInt)
	if err != nil {
		return err
	}
	_ = stmtIn.Close()
	result := "通过了!"
	if askResultInt == -1 {
		result = "被拒绝了"
	}
	messageBean := MessageBean{
		ToUserId:       userId,
		MessageType:    code.TypePushAskForLeave,
		MessageContent: fmt.Sprintf("你的请假已经%v", result),
		MessageAppend:  askForLeaveId,
	}
	err = MessageCreate(messageBean)
	//向请假人推送
	push.Push(userId, code.TypePushAskForLeave, messageBean)
	return nil
}
